package com.syf.kit.soa.core.send.protocol.handle;

import com.syf.kit.soa.core.SyfRpcMsg;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

@Slf4j
public class RpcDataDecoder extends ByteToMessageDecoder {

    /**
     * 魔数（2byte） + 版本号（2byte）+ 请求类型（1byte）+ 业务报文类型（1byte） + 调用计数（4byte） + 请求uuid（8byte）
     * + 交易码(10byte) + 保留域（4byte） + 业务报文的byte长度（4byte） + 业务报文(n byte)
     */
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> list) throws Exception {
        // 标记初始
        byteBuf.markReaderIndex();

        /**
         * 判定请求数据是否完整，不完整下次再收取
         * */
        if (byteBuf.readableBytes() >= 36) {
            byteBuf.skipBytes(32);
            int bizDataLen = byteBuf.readInt();
            if (byteBuf.readableBytes() < bizDataLen) {
                byteBuf.resetReaderIndex();
                log.trace("数据未收全，退回去！");
                return;
            }
        }

        byteBuf.resetReaderIndex();
        SyfRpcMsg syfRpcMsg = new SyfRpcMsg();
        byte[] magicNum_BYTES = new byte[2];
        byte[] version_BYTES = new byte[2];
        byteBuf.readBytes(magicNum_BYTES).readBytes(version_BYTES);
        syfRpcMsg.setMagicNum(new String(magicNum_BYTES));
        syfRpcMsg.setVersion(new String(version_BYTES));

        syfRpcMsg.setReqType(byteBuf.readByte());
        syfRpcMsg.setBizDataType(byteBuf.readByte());
        syfRpcMsg.setCallCount(byteBuf.readInt());
        syfRpcMsg.setReqUUID(byteBuf.readLong());

        byte[] serviceCode_BYTES = new byte[10];
        byteBuf.readBytes(serviceCode_BYTES);
        String serviceCode = new String(serviceCode_BYTES);
        syfRpcMsg.setServiceCode(serviceCode.trim());

        byte[] reserved_BYTES = new byte[4];
        byteBuf.readBytes(reserved_BYTES);
        syfRpcMsg.setReserved(reserved_BYTES);

        syfRpcMsg.setBizDataLen(byteBuf.readInt());

        byte[] bizData_BYTES = new byte[syfRpcMsg.getBizDataLen()];
        byteBuf.readBytes(bizData_BYTES);
        syfRpcMsg.setBizData(new String(bizData_BYTES));

        list.add(syfRpcMsg);
    }
}
